package com.gitee.wsl.ext.collection


/**
 * @param set1
 * Some set.
 * @param set2
 * Some other set.
 * @param <T>
 * Item type.
 *
 * @return Iterator over all values among both sets.
</T> */

fun <T> iterator(set1: Set<T>?,set2: Set<T>?): Iterator<T> {
    if (set1 == null && set2 == null) return emptyList<T>().iterator()
    else if (set1 == null) return set2!!.iterator()
    else if (set2 == null) return set1.iterator()
    return MergedSetIterator(set1, set2)
}

/**
 * Set iterator visiting the unique items of two distinct sets.
 *
 * @param <T>
 * Item type.
</T> */
private class MergedSetIterator<T>(left: Set<T>, right: Set<T>) : Iterator<T> {
    private val leftIt: Iterator<T> = left.iterator()
    private val rightIt: Iterator<T> = right.iterator()
    private val seen: IntArray = IntArray(left.size + right.size)
    private var i = 0

     override fun hasNext(): Boolean {
        return leftIt.hasNext() || rightIt.hasNext()
    }

     override fun next(): T {
        val next = if (leftIt.hasNext()) leftIt.next() else rightIt.next()
        val nextHash = next.hashCode()
        val max = i
        i++
        for (j in 0..<max) {
            if (seen[j] == nextHash) return next()
        }
        seen[i] = nextHash
        return next
    }
}